# coding:utf-8 

from genericpath import exists
import sqlite3
import re
from warnings import catch_warnings
import string

class ar():
    def __init__(self):
#        self.nazov='prazdny nazov'
        self.udaje=udaje()
        self.startovka=startovka()
        self.behy=behy()
        self.sucty=sucty()
        self.aktualnyBeh=0;
        self.aktualnyTim=0;
        self.casomiera=casomiera()
        self.aktualnaStartovka={}
        self.vysledky=vysledky()
        self.bodyJumping=[18,15,13,12,11,10,9,8,7,6,5,4,3,2,1]
        self.bodyAgility=[25,20,17,14,12,10,9,8,7,6,5,4,3,2,1]
    def load(self,filename):
        if (filename[-4:]<>'.agi'):
            filename=filename+'.agi'
        if exists(filename):
            print 'nacitam '+filename
            self.sql = sqlite3.connect(filename)
            self.nacitaj_preteky()
        else:
            print 'vytvaram prazdne preteky... '+filename
            self.sql = sqlite3.connect(filename)
            self.sql.text_factory = sqlite3.OptimizedUnicode
            self.vytvor_prazdne_preteky()
    def vytvor_prazdne_preteky(self):
        cur=self.sql.cursor()
        cur.executescript('''create table udaje (name text,value text);
insert into udaje values ('nazov','');
insert into udaje values ('datum','');
insert into udaje values ('organizator','');
insert into udaje values ('garant','');
insert into udaje values ('rozhodca','');
insert into udaje values ('logo','');

create table startovka (id int, kategoria text, meno text, priezvisko text, klub text, pes text, plemeno text, pp int, vz text, merat int, email text, tel text, krajina text);
create table behy (id int, nazov text, typ text, datum text, rozhodca text, filter text, dlzka real, stdcas real, maxcas real, prekazky int, created int);
create table vysledkyraw (behid int, timid int, cas real, chy int, odm int, tbcas real, tb real, hod text, created int);
create table vysledky (behid int, timid int, cas real, chy int, odm int, tbcas real, tb real, hod text, poradie int, body int, created int);
create table sucty (id int, nazov text, typ int, behy text, filter text);
create table casomieralog(behid int, timid int, cas real, created int);''')

    def nacitaj_preteky(self):
        print 'nacitam preteky'
        cur=self.sql.cursor()
        cur.execute('''select * from udaje order by name''')
        self.udaje.set(cur.fetchall())
        cur.execute('''select * from behy order by id''')
        self.behy.set(cur.fetchall())
        cur.execute('''select * from sucty order by id''')
        self.sucty.set(cur.fetchall())
        #self.save_udaje()
        cur.execute('''select * from startovka order by id''')
        self.startovka.set(cur.fetchall())
        cur.execute('''select * from vysledky order by behid,poradie,timid''')
        self.vysledky.set(cur.fetchall())
        cur.execute('''select * from vysledkyraw order by behid,timid''')
        self.vysledky.setraw(cur.fetchall())
        #self.data.set(self.sql.execute('''select * from udaje order by id'''))
    def save_udaje(self):
        cur=self.sql.cursor()
        for key,value in self.udaje.get():
            #print 'ukladam '+key+' '+value
            cur.execute('update udaje set value=? where name=?', (value,key))
        self.sql.commit()
    def save_behy(self):
        cur=self.sql.cursor()
        cur.execute('delete from behy')
        for behid,bd in self.behy.get():
            #print 'ukladam beh '+str(behid)
            #print bd
            cur.execute('insert into behy values (?,?,?,?,?,?,?,?,?,?,current_timestamp)', (behid,bd[0],bd[1],bd[2],bd[3],bd[4],bd[5],bd[6],bd[7],bd[8]))
        self.sql.commit()
    def save_startovka(self):
        cur=self.sql.cursor()
        cur.execute('delete from startovka')
        #print 'startovka: '
        #print self.startovka.get()
        for sid,sd in self.startovka.get():
            #print 'ukladam zaznam '+str(sid)
            #print sd
            #print len(sd)
            cur.execute('insert into startovka values (?,?,?,?,?,?,?,?,?,?,?,?,?)', \
                (sid,sd[0],sd[1],sd[2],sd[3],sd[4],sd[5],sd[6],sd[7],sd[8],sd[9],sd[10],sd[11]))
        self.sql.commit()
    def setVysledok(self,behid,timid,cas,chy,odm,tbcas,nest,dis,commit):
        self.vysledky.setVysledok(behid, timid, cas, chy, odm, tbcas, nest, dis)
        self.save_vysledok(behid,timid,commit)
        #self.vysledky.dataraw[behid][timid]
    def save_vysledok(self,behid,timid,commit):
        cur=self.sql.cursor()
        cur.execute('delete from vysledkyraw where behid=? and timid=?',(behid, timid))
        v=self.vysledky.dataraw[behid][timid]
        cur.execute('insert into vysledkyraw values (0,?,?,?,?,?,?,?,?,0)', \
                    (behid, timid, v[2], v[3], v[4], v[5], v[6], v[7]))
        #print self.vysledky.dataraw[behid][timid]
        if commit:
            self.sql.commit()
    def finalizeVysledky(self, behid):
        beh=self.behy.get(1)[behid]
        #std cas 6, max cas 7
        tosort={}
        final={}
        for timid in self.aktualnaStartovka:
            v=list(self.vysledky.get(behid, timid))
            #cas 2, ch 3, odm 4, tbcas 5, tb 6
            if v[6]<100:
                v[5]=0 if v[2]<beh[6] else v[2]-beh[6]
                if (v[2]>beh[7]):
                    v[6]=100
                else:
                    v[6]=v[5]+5*(v[3]+v[4])
            tosort[timid]=tuple(v)
            self.setVysledok(behid, timid, v[2], v[3], v[4], v[5], True if v[6]==200 else False, True if v[6]==100 else False,False)
        poradie=1
        body=self.bodyJumping if str(beh[1]).find('umping')>-1 else self.bodyAgility
        for key in sorted(tosort, key=tosort.__getitem__, cmp=fciSort):
            r=tosort[key]
            final[poradie]=(r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], poradie if r[6]<100 else '-', body[poradie-1] if poradie<=15 and r[6]<100 else 0, poradie)
            poradie+=1
        cur=self.sql.cursor()
        cur.execute('delete from vysledky where behid=?',(behid, ))
        self.sql.commit()
        for k in final:
            v=final[k]
            cur.execute('insert into vysledky values (?,?,?,?,?,?,?,?,?,?,?,0)', \
                    (v[10],behid, v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9]))
            
#create table vysledky (0behid int,1timid int,2 cas real,3chy int, 4odm int, 5tbcas real, 6tb real, 7hod text, 8poradie int, 9body int, 10created int);
#                    self.data[d[1]][d[2]]=(d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10])

            
            try:
                self.vysledky.data[behid][v[1]]=(behid, v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10])
            except KeyError:
                self.vysledky.data[behid]={}
                self.vysledky.data[behid][v[1]]=(behid, v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10])
        self.sql.commit()
    
    
    def getSucet(self, sucetid):
        sucet=self.sucty.get(1)[sucetid]
        #print sucet
        typ=sucet[1] #typ suctu, 1=FCI, 2=body
        filter=sucet[3]
        behy=string.split(sucet[2], ';')
        startovka={}
        vyscache={}
        vyscache2={}
        vystotal={}
        behdata={}
        for id,zaznam in self.startovka.get():
            if filter=="PP":
                if zaznam[6]==1:
                    startovka[id]=zaznam
            else:
                startovka[id]=zaznam
        for beh in behy:
            #print "beh"+beh
            behdata[int(beh)]=self.behy.get(1)[int(beh)]
            vysledky=self.vysledky.getBeh(int(beh))
            #print vysledky
            for v in vysledky:
            #    print v, vysledky[v]
                if v in startovka:
                    if not v in vyscache:
                        vyscache[v]={}
                    if not beh in vyscache[v]:
                        vyscache[v][int(beh)]={}
                    vyscache[v][int(beh)]=vysledky[v]
        for tim in vyscache:
            vystotal[tim]=[0,0,0,0,0,0,0] #body, body agility, cas, fake, fake, fake, tb
            for beh in behy:
                #ak je to agility beh, zapisem body
                if tim in vyscache:
                    if not int(beh) in vyscache[tim]:
                        vyscache[tim][int(beh)]=[0,0,0,0,0,0,200,0,0,0]
                if not str(behdata[int(beh)]).find('umping')>-1:
                    vystotal[tim][1]=vystotal[tim][1]+vyscache[tim][int(beh)][9]
                #cas
                vystotal[tim][2]=vystotal[tim][2]+vyscache[tim][int(beh)][2]
                #tbcas
                vystotal[tim][5]=vystotal[tim][5]+vyscache[tim][int(beh)][5]
                #tb
                vystotal[tim][6]=vystotal[tim][6]+vyscache[tim][int(beh)][6]
                #body
                vystotal[tim][0]=vystotal[tim][0]+vyscache[tim][int(beh)][9]
                    
        #print vyscache

        poradie=1;
        if typ==1: #FCI sucet
            for key in sorted(vystotal, key=vystotal.__getitem__, cmp=fciSort):
                r=vystotal[key]
                vyscache2[poradie]=list((key,r))
                poradie+=1
        else: #bodovy system
            for key in sorted(vystotal, key=vystotal.__getitem__, cmp=pointSort):
                r=vystotal[key]
                vyscache2[poradie]=list((key,r))
                poradie+=1
        return vyscache2, vyscache

class udaje():
    def __init__(self):
        self.data={}
    def set(self,data):
        for udaj in data:
            self.data[udaj[0]]=udaj[1]
            #print 'nastavujem '+udaj[0]+ ' '+udaj[1]
    def get(self, format=0):
        if (format==0):
            return self.data.items()
        else:
            return self.data
        
class startovka():
    def __init__(self):
        self.data=[]

    def set(self,data):
        self.data={}
        for udaj in data:
            self.data[udaj[0]]=(udaj[1],udaj[2],udaj[3],udaj[4],udaj[5],udaj[6],udaj[7],udaj[8],udaj[9],udaj[10],udaj[11],udaj[12])
    def get(self, format=0):
        if (format==0):
            return self.data.items()
        elif (format==2): #format pre tlac
            out=[]
            for row in sorted(self.data, key=self.data.__getitem__, cmp=katSort):
            #for row in self.data:
                print self.data[row]
                #(u'Č.',u'Kat.',u'Meno psovoda',u'Klub',u'Meno psa',u'Plemeno',u'')
                out.append(list((row,self.data[row][0],
                                 self.data[row][1]+' '+self.data[row][2],
                                 self.data[row][3],
                                 self.data[row][4],
                                 self.data[row][5]+(' (PP)' if self.data[row][6]==1 else ''),
                                 self.data[row][11]
                                 )))
                #TODO simulujem plnsi stav :)
            return out
        else:
            return self.data 
class vysledky():
    def __init__(self):
        self.status=0
        self.data={}
        self.dataraw={}
    def set(self,data):
        for d in data:
            #create table vysledky (0behid int,1timid int,2 cas real,3chy int, 4odm int, 5tbcas real, 6tb real, 7hod text, 8poradie int, 9body int, 10created int);
            try:
                self.data[d[1]][d[2]]=(d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10])
            except KeyError:
                self.data[d[1]]={}
                self.data[d[1]][d[2]]=(d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10])
    def setraw(self,data):
        for d in data:
            #create table vysledkyraw (0behid int, 1timid int, 2cas real, 3chy int, 4odm int, 5tbcas real, 6tb real, 7hod text, 8created int);
            try:
                self.dataraw[d[1]][d[2]]=(d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9])
            except KeyError:
                self.dataraw[d[1]]={}
                self.dataraw[d[1]][d[2]]=(d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9])
    def get0(self,behid,timid):
        #nastav vysledky na zobrazovanie
        bv=self.dataraw.get(behid,{})
        return bv.get(timid, (behid, timid, 0, 0, 0, 0, 0, '', 0, 0, 0))
    def get(self,behid,timid):
        #zisti uz zapisane vysledky, ak nic, tak nestartoval
        bv=self.dataraw.get(behid,{})
        return bv.get(timid, (behid, timid, 0, 0, 0, 0, 200, '-', 0, 0, 0))
    def getBeh(self,behid):
        try:
            return self.data[behid]
        except KeyError:
            return {}
    def setVysledok(self,behid,timid,cas,chy,odm,tbcas,nest,dis):
        tb=tbcas+(chy+odm)*5
        if (nest):
            tb=200;
        if (dis):
            tb=100;
        try:
            self.dataraw[behid][timid]=(behid, timid,cas,chy,odm,tbcas,tb,self.hodnotenie(tb),0)
        except KeyError:
            self.dataraw[behid]={}
            self.dataraw[behid][timid]=(behid, timid,cas,chy,odm,tbcas,tb,self.hodnotenie(tb),0)
    def hodnotenie(self,tb):
        if tb<6:
            return 'V'
        elif tb<16:
            return 'VD'
        elif tb<26:
            return 'D'
        elif tb==100:
            return 'DIS'
        elif tb==200:
            return '-'
        else:
            return 'BO'
class behy():
    def __init__(self):
        self.data={}
    def set(self,data):
        #print 'vstupne data na behy.set()'
        #print data
        self.data={}
        for udaj in data:
            self.data[udaj[0]]=(udaj[1],udaj[2],udaj[3],udaj[4],udaj[5],udaj[6],udaj[7],udaj[8],udaj[9],udaj[10])
            #print 'nastavujem beh'+str(udaj[0])+ ' '+udaj[1]
        #print 'interne data behy.data'
        #print self.data
    def get(self, format=0):
        if (format==0):
            return self.data.items()
        else:
            return self.data
class sucty():
    def __init__(self):
        self.data={}
    def set(self,data):
        self.data={}
        for udaj in data:
            self.data[udaj[0]]=(udaj[1],udaj[2],udaj[3],udaj[4])
            #print 'nastavujem beh'+str(udaj[0])+ ' '+udaj[1]
        #print 'interne data behy.data'
        #print self.data
    def get(self, format=0):
        if (format==0):
            return self.data.items()
        else:
            return self.data
        
        
class casomiera():
    def __init__(self):
        self.cas=float(0)
        self.bezim=False
        self.historia=[]
        self.cas0=float(0)
        self.tb=0
        self.chy=0
        self.odm=0

#fci sorting algorithm
def fciSort(a, b):
    #6 tb, 2 cas, 5tbcas
    # naprv zoradim podla TB
    if a[6]>b[6]:
        return 1
    elif b[6]>a[6]:
        return -1
    else:
        #ak je zhoda TB, tak podla casu, vynimku tvori pripad, kedy tbcas>0
        #5 = tbcas
        if a[6]>0:
            if a[5]<b[5]:
                return 1
            elif a[5]>b[5]:
                return -1
            else:
                if a[2]>b[2]:
                    return 1
                elif a[2]<b[2]:
                    return -1
                else:
                    return 0
#                return 0
        else:
            #ak tb=0
            if a[2]>b[2]:
                return 1
            elif a[2]<b[2]:
                return -1
            else:
                return 0
#point sorting algorithm
def pointSort(a, b):
    #6 tb, 2 cas, 5tbcas, 0body, 1body agility
    # naprv zoradim podla bodov
    if a[0]<b[0]:
        return 1
    elif a[0]>b[0]:
        return -1
    else:
        #ak je zhoda bodov, tak podla bodov v agility behu na indexe 1 
        if a[1]<b[1]:
            return 1
        elif a[1]>b[1]:
            return -1
        else:
            return 0
def katSort(a, b):
    #SA1, SA2, SA3, MA1, MA2, MA3, LA1, LA2, LA3
    ha=a[0][0:1]
    hb=b[0][0:1]
    la=a[0][2:3]
    lb=b[0][2:3]
    print ha, la, ' vs. ', hb, lb
    if ha==hb:
        if la==lb:
            return 0
        else:
            return 1 if la>lb else -1 
    else:
        if ha=='S':
            return -1
        elif ha=='M':
            return 1 if hb=='S' else -1
        else:
            return 1
